<!DOCTYPE html>
<html lang="zh_cn">
<head>
          <title>来玩魔王的咚</title>
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <meta charset="utf-8" />
        <!-- twitter card metadata -->
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="/images/mowang.png">
<meta name="twitter:site" content="">
<meta name="twitter:title" content="基于Python的Pelican打造静态网站">
<meta name="twitter:description" content="<p>Pelican使用指南：安装，使用markdown写文章，生成静态页面，通过gitee发布，关于主题，添加插件；经验技巧：Markdown中使用锚点，代码高亮显示</p>">
        <!-- OG Tags -->
<meta property="og:url" content="/use-pelican-make-website.html"/>
<meta property="og:title" content="来玩魔王的咚 | 基于Python的Pelican打造静态网站" />
<meta property="og:description" content="<p>Pelican使用指南：安装，使用markdown写文章，生成静态页面，通过gitee发布，关于主题，添加插件；经验技巧：Markdown中使用锚点，代码高亮显示</p>" />
        <!-- favicon -->
        <link rel="icon" type="image/png" href="/images/mowang.png">
        <!-- moment.js for date formatting -->
        <script src="/theme/js/moment.js"></script>
        <!-- css -->
        <link rel="stylesheet" type="text/css" href="/theme/css/main.css" />
        <!-- 左边的menu，如果页面高度不够，就跟着滚动，否则文章分类显示不全 -->
        <link rel="stylesheet" type="text/css" href="/theme/css/mycss/menu.css" />
		<script>
			
                /*! grunt-grunticon Stylesheet Loader - v2.1.2 | https://github.com/filamentgroup/grunticon | (c) 2015 Scott Jehl, Filament Group, Inc. | MIT license. */
    
    (function(e){function t(t,n,r,o){"use strict";function a(){for(var e,n=0;u.length>n;n++)u[n].href&&u[n].href.indexOf(t)>-1&&(e=!0);e?i.media=r||"all":setTimeout(a)}var i=e.document.createElement("link"),l=n||e.document.getElementsByTagName("script")[0],u=e.document.styleSheets;return i.rel="stylesheet",i.href=t,i.media="only x",i.onload=o||null,l.parentNode.insertBefore(i,l),a(),i}var n=function(r,o){"use strict";if(r&&3===r.length){var a=e.navigator,i=e.Image,l=!(!document.createElementNS||!document.createElementNS("http://www.w3.org/2000/svg","svg").createSVGRect||!document.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#Image","1.1")||e.opera&&-1===a.userAgent.indexOf("Chrome")||-1!==a.userAgent.indexOf("Series40")),u=new i;u.onerror=function(){n.method="png",n.href=r[2],t(r[2])},u.onload=function(){var e=1===u.width&&1===u.height,a=r[e&&l?0:e?1:2];n.method=e&&l?"svg":e?"datapng":"png",n.href=a,t(a,null,null,o)},u.src="",document.documentElement.className+=" grunticon"}};n.loadCSS=t,e.grunticon=n})(this);(function(e,t){"use strict";var n=t.document,r="grunticon:",o=function(e){if(n.attachEvent?"complete"===n.readyState:"loading"!==n.readyState)e();else{var t=!1;n.addEventListener("readystatechange",function(){t||(t=!0,e())},!1)}},a=function(e){return t.document.querySelector('link[href$="'+e+'"]')},c=function(e){var t,n,o,a,c,i,u={};if(t=e.sheet,!t)return u;n=t.cssRules?t.cssRules:t.rules;for(var l=0;n.length>l;l++)o=n[l].cssText,a=r+n[l].selectorText,c=o.split(");")[0].match(/US\-ASCII\,([^"']+)/),c&&c[1]&&(i=decodeURIComponent(c[1]),u[a]=i);return u},i=function(e){var t,o,a;o="data-grunticon-embed";for(var c in e)if(a=c.slice(r.length),t=n.querySelectorAll(a+"["+o+"]"),t.length)for(var i=0;t.length>i;i++)t[i].innerHTML=e[c],t[i].style.backgroundImage="none",t[i].removeAttribute(o);return t},u=function(t){"svg"===e.method&&o(function(){i(c(a(e.href))),"function"==typeof t&&t()})};e.embedIcons=i,e.getCSS=a,e.getIcons=c,e.ready=o,e.svgLoadedCallback=u,e.embedSVG=u})(grunticon,this);
                
                grunticon(["/theme/css/icons.data.svg.css", "/theme/css/icons.data.png.css", "/theme/css/icons.fallback.css"]);
            </script>
        <noscript><link href="/theme/css/icons.fallback.css" rel="stylesheet"></noscript>
        <!-- menu toggle javascript -->
        <script type="text/javascript">
            document.addEventListener("DOMContentLoaded", initMenu);
            
            function initMenu(){
                var menu = document.getElementById("menu");
                var menulink = document.getElementById("menu-link");
                menulink.addEventListener("click", function toggleMenu(){
                        window.event.preventDefault();
                        menulink.classList.toggle('active');
                        menu.classList.toggle('active');              
                    });
            };
        </script>
        <!-- 不蒜子 -->
        <script async src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>

    <meta name="description" content="<p>Pelican使用指南：安装，使用markdown写文章，生成静态页面，通过gitee发布，关于主题，添加插件；经验技巧：Markdown中使用锚点，代码高亮显示</p>" />

    <meta name="tags" content="pelican" />
    <meta name="tags" content="markdown" />
  <!-- 替换部分base的样式，看文章时，要再宽一点，右边有很多空间可以撑开 -->
  <link rel="stylesheet" type="text/css" href="/theme/css/mycss/article.css" />

</head>
<body>
    <div role="banner" id="masthead">
        <header>
            <a href="/"><img src="/images/mowang.png" alt="McManus Logo"></a>
                <h1>来玩魔王的咚@骑士救兵</h1>
            <a href="#menu" id="menu-link">more stuff</a>
            <nav id="menu">
                <ul>
                        <li><a href="/tags">tags</a></li>
                            <li><a href="/category/cloud.html">Cloud</a></li>
                            <li><a href="/category/docker.html">Docker</a></li>
                            <li><a href="/category/go.html">Go</a></li>
                            <li><a href="/category/linux.html">Linux</a></li>
                            <li class="active"><a href="/category/python.html">Python</a></li>
                            <li><a href="/category/xue-xi-bi-ji.html">学习笔记</a></li>
                            <li><a href="/category/yun-wei-zi-dong-hua.html">运维自动化</a></li>
                </ul>
            </nav>
        </header>
    </div>
        <div class="page" role="main">
  <div class="article" role="article">
    <article>
        <footer>
            <a name="top"></a>
            <p>
              <time datetime=" 2020-06-29 19:41:00+08:00">
                <script>document.write(moment('2020-06-29 19:41:00+08:00').format('LL'));</script>
              </time>
              ~
              <time datetime=" 2020-06-29 19:41:00+08:00">
                <script>document.write(moment('2022-03-31 12:29:00+08:00').format('LL'));</script>
              </time>
            </p>
        </footer>
        <header>
          <h2>
            基于Python的Pelican打造静态网站
          </h2>
        </header>
      <div class="content">
         <div class="toc">
<ul>
<li><a href="#an-zhuang-pelican">安装 Pelican</a><ul>
<li><a href="#chuang-jian-xu-ni-huan-jing">创建虚拟环境</a></li>
<li><a href="#pip-an-zhuang-pelican">pip 安装 Pelican</a></li>
<li><a href="#chu-shi-hua-an-zhuang">初始化安装</a></li>
</ul>
</li>
<li><a href="#xie-wen-zhang">写文章</a><ul>
<li><a href="#sheng-cheng-jing-tai-ye">生成静态页</a></li>
<li><a href="#ben-di-liu-lan-wang-ye">本地浏览网页</a></li>
<li><a href="#wen-jian-yuan-shu-ju">文件元数据</a></li>
</ul>
</li>
<li><a href="#shang-chuan-dao-gitee">上传到gitee</a><ul>
<li><a href="#chuang-jian-xiang-mu">创建项目</a></li>
<li><a href="#shang-chuan-wen-jian">上传文件</a></li>
<li><a href="#kai-qi-gitee-pages-fu-wu">开启 Gitee Pages 服务</a></li>
</ul>
</li>
<li><a href="#she-zhi-zhu-ti">设置主题</a><ul>
<li><a href="#jiang-zhu-ti-cang-ku-ke-long-dao-ben-di">将主题仓库克隆到本地</a></li>
<li><a href="#pei-zhi-shi-yong-zhu-ti">配置使用主题</a></li>
<li><a href="#ying-yong-zhu-ti">应用主题</a></li>
<li><a href="#guan-yu-xiu-gai-zhu-ti">关于修改主题</a></li>
</ul>
</li>
<li><a href="#tian-jia-cha-jian">添加插件</a><ul>
<li><a href="#xia-zai-cha-jian">下载插件</a></li>
<li><a href="#pei-zhi-bing-ying-yong-cha-jian">配置并应用插件</a></li>
</ul>
</li>
<li><a href="#jing-yan-he-ji-qiao">经验和技巧</a><ul>
<li><a href="#markdown-shi-yong-mao-dian">Markdown 使用锚点</a></li>
<li><a href="#dai-ma-gao-liang-xian-shi">代码高亮显示</a></li>
</ul>
</li>
</ul>
</div>
<p>中文官方文档：<br>
https://pelican-docs-latest-cn.readthedocs.io/zh_CN/latest/index.html</p>
<h3 id="an-zhuang-pelican"><a class="toclink" href="#an-zhuang-pelican">安装 Pelican</a></h3>
<p>可以方便是使用pip完成安装，不过还是建议先创建一个单独的虚拟环境，然后再安装。</p>
<h4 id="chuang-jian-xu-ni-huan-jing"><a class="toclink" href="#chuang-jian-xu-ni-huan-jing">创建虚拟环境</a></h4>
<p>可以使用如下的命令创建虚拟环境：</p>
<div class="highlight"><pre><span></span><code><span class="gp">$ </span>python -m venv pelican               <span class="c1"># 创建虚拟环境</span>
<span class="gp">$ </span><span class="nb">cd</span> pelican/Scripts
<span class="gp">$ </span>python -m pip install --upgrade pip  <span class="c1"># 更新pip</span>
</code></pre></div>

<h4 id="pip-an-zhuang-pelican"><a class="toclink" href="#pip-an-zhuang-pelican">pip 安装 Pelican</a></h4>
<p>之后还是要用markdown来写文档的，所以用下面的方法把markdown一起装上：</p>
<div class="highlight"><pre><span></span><code><span class="gp">$ </span>pip install pelican<span class="o">[</span>Markdown<span class="o">]</span>
</code></pre></div>

<p>安装完成后可以运行下帮助看看：</p>
<div class="highlight"><pre><span></span><code><span class="gp">$ </span>pelican --help
<span class="gp">$ </span>pelican --version
<span class="go">4.2.0</span>
</code></pre></div>

<p>太多了，还是先看个version吧。</p>
<h4 id="chu-shi-hua-an-zhuang"><a class="toclink" href="#chu-shi-hua-an-zhuang">初始化安装</a></h4>
<p>首先，要创建一个项目。然后cd到项目的目录中:</p>
<div class="highlight"><pre><span></span><code><span class="gp">$ </span>mkdir -p ~/projects/yoursite
<span class="gp">$ </span><span class="nb">cd</span> ~/projects/yoursite
</code></pre></div>

<p>运行 pelican-quickstart 命令，初始化项目框架。执行命令前确认切换到了正确的虚拟环境。<br>
运行命令后，会提示一些关于这个项目的基础配置问题。括号中带有默认值，之后也可以在配置文件中进行修改。<br>
具体如下：</p>
<div class="highlight"><pre><span></span><code><span class="gp">$ </span>pelican-quickstart
<span class="go">Welcome to pelican-quickstart v4.2.0.</span>

<span class="go">This script will help you create a new Pelican-based website.</span>

<span class="go">Please answer the following questions so this script can generate the files</span>
<span class="go">needed by Pelican.</span>


<span class="go">&gt; Where do you want to create your new web site? [.]</span>
<span class="go">&gt; What will be the title of this web site? 骑士救兵的技术博客</span>
<span class="go">&gt; Who will be the author of this web site? 749B</span>
<span class="go">&gt; What will be the default language of this web site? [Chinese (Simplified)] zh_cn</span>
<span class="go">Entry must be 2 characters long</span>
<span class="go">&gt; What will be the default language of this web site? [Chinese (Simplified)] zh</span>
<span class="go">&gt; Do you want to specify a URL prefix? e.g., https://example.com   (Y/n) n</span>
<span class="go">&gt; Do you want to enable article pagination? (Y/n) y</span>
<span class="go">&gt; How many articles per page do you want? [10]</span>
<span class="go">&gt; What is your time zone? [Europe/Paris] Asia/Shanghai</span>
<span class="go">&gt; Do you want to generate a tasks.py/Makefile to automate generation and publishing? (Y/n) y</span>
<span class="go">&gt; Do you want to upload your website using FTP? (y/N) n</span>
<span class="go">&gt; Do you want to upload your website using SSH? (y/N) n</span>
<span class="go">&gt; Do you want to upload your website using Dropbox? (y/N) n</span>
<span class="go">&gt; Do you want to upload your website using S3? (y/N) n</span>
<span class="go">&gt; Do you want to upload your website using Rackspace Cloud Files? (y/N) n</span>
<span class="go">&gt; Do you want to upload your website using GitHub Pages? (y/N) y</span>
<span class="go">&gt; Is this your personal page (username.github.io)? (y/N) y</span>
<span class="go">Done. Your new project is available at</span>
</code></pre></div>

<p>时区: Asia/Shanghai<br>
这里中文语言是zh_cn，但是通不过，只能之后再去文件 pelicanconf.py 中修改：</p>
<div class="highlight"><pre><span></span><code><span class="n">TIMEZONE</span> <span class="o">=</span> <span class="s1">&#39;Asia/Shanghai&#39;</span>

<span class="n">DEFAULT_LANG</span> <span class="o">=</span> <span class="s1">&#39;zh_cn&#39;</span>
</code></pre></div>

<p>执行完成后，会生成如下的目录结构：</p>
<div class="highlight"><pre><span></span><code>yourproject/
├── content
│   └── (pages)
├── output
├── tasks.py
├── Makefile
├── pelicanconf.py  # Main settings file
└── publishconf.py  # Settings to use when ready to publish
</code></pre></div>

<h3 id="xie-wen-zhang"><a class="toclink" href="#xie-wen-zhang">写文章</a></h3>
<p>把写好的markdown保存到content目录下。在content目录下创建markdown文件：第一篇文章.md</p>
<div class="highlight"><pre><span></span><code>Title: Pelican的第一篇文章
Date: 2020-06-29 19:41
Category: Python
Tags: pelican, publishing
Slug: my-super-post
Summary: 文章摘要

这是我的第一篇文章
</code></pre></div>

<p>开头的部分是元数据，只有标题(Title)是必须的，另外也是有办法不要标题，改为从文件名获取标题的。<br>
Slug 是之后生成的html文件的文件名。名字可以稍微长一点，建议用中横杠分词。  </p>
<h4 id="sheng-cheng-jing-tai-ye"><a class="toclink" href="#sheng-cheng-jing-tai-ye">生成静态页</a></h4>
<p>执行下面的命令就可以自动生成静态网页：</p>
<div class="highlight"><pre><span></span><code><span class="gp">$ </span>pelican content
</code></pre></div>

<p>执行完成后，生成的网页都保存在output目录中。</p>
<h4 id="ben-di-liu-lan-wang-ye"><a class="toclink" href="#ben-di-liu-lan-wang-ye">本地浏览网页</a></h4>
<p>执行下面的命令，启动Pelican的web服务:</p>
<div class="highlight"><pre><span></span><code><span class="gp">$ </span>pelican --listen
</code></pre></div>

<p>之后可以通过 http://localhost:8000  在本地浏览。</p>
<h4 id="wen-jian-yuan-shu-ju"><a class="toclink" href="#wen-jian-yuan-shu-ju">文件元数据</a></h4>
<p>上面只用到了部分元数据，所有支持的元数据如下，按需添加吧。<br>
元数据也支持自定义，关键字随意，不要和下面列出来的冲突即可。<br>
Metadata Description: </p>
<ul>
<li>title: Title of the article or page</li>
<li>date: Publication date (e.g., YYYY-MM-DD HH:SS)</li>
<li>modified: Modification date (e.g., YYYY-MM-DD HH:SS)</li>
<li>tags: Content tags, separated by commas</li>
<li>keywords: Content keywords, separated by commas (HTML content only)</li>
<li>category: Content category (one only — not multiple)</li>
<li>slug: Identifier used in URLs and translations</li>
<li>author: Content author, when there is only one</li>
<li>authors: Content authors, when there are multiple</li>
<li>summary: Brief description of content for index pages</li>
<li>lang: Content language ID (en, fr, etc.)</li>
<li>translation: Is content is a translation of another (true or false)</li>
<li>status: Content status: draft, hidden, or published</li>
<li>template: Name of template to use to generate content (without extension)</li>
<li>save_as: Save content to this relative file path</li>
<li>url: URL to use for this article/page</li>
</ul>
<h3 id="shang-chuan-dao-gitee"><a class="toclink" href="#shang-chuan-dao-gitee">上传到gitee</a></h3>
<p>静态网页已经生成了，之后就是发布出来了。  </p>
<h4 id="chuang-jian-xiang-mu"><a class="toclink" href="#chuang-jian-xiang-mu">创建项目</a></h4>
<p><strong>如何创建一个首页访问地址不带二级目录的 pages，如<code>yourname.gitee.io</code></strong><br>
项目名称可以任意，不过最好是使用账号名同名的名称。<br>
使用和账号名同名的名称，就可以通过<code>yourname.gitee.io</code>这样的一级目录来访问。<br>
否则只能通过<code>username.gitee.com/projectname</code>这样的二级子目录来访问。  </p>
<h4 id="shang-chuan-wen-jian"><a class="toclink" href="#shang-chuan-wen-jian">上传文件</a></h4>
<p>只需要把 output 文件夹里所有的内容（不包括目录本身），上传到项目中即可。<br>
不过也可以把其他部分也一起上传。之后在开启服务的时候，需要设置一下发布的目录。  </p>
<h4 id="kai-qi-gitee-pages-fu-wu"><a class="toclink" href="#kai-qi-gitee-pages-fu-wu">开启 Gitee Pages 服务</a></h4>
<p>去项目中开启服务：Service -&gt; Gitee Pages<br>
Deploy directory 选项中选择要发布的目录：</p>
<ul>
<li>如果只上传了output文件夹中的内容，空着默认即可</li>
<li>如果发布内容是在某个文件夹内的，则把包含静态页面的文件夹的路径填进去</li>
</ul>
<h3 id="she-zhi-zhu-ti"><a class="toclink" href="#she-zhi-zhu-ti">设置主题</a></h3>
<p>这里没用官方文档建议的方式。<br>
可以到下面这个网站查看各种主题的效果:<br>
http://www.pelicanthemes.com/</p>
<h4 id="jiang-zhu-ti-cang-ku-ke-long-dao-ben-di"><a class="toclink" href="#jiang-zhu-ti-cang-ku-ke-long-dao-ben-di">将主题仓库克隆到本地</a></h4>
<p>cd到博客更目录：</p>
<div class="highlight"><pre><span></span><code><span class="gp">$ </span>git clone https://github.com/getpelican/pelican-themes.git
</code></pre></div>

<p>这里把克隆下来的 pelican-themes 目录放在和 content 以及 output 的同一级目录。  </p>
<p>由于很多主题都有独立的仓库，所以用上面的方法克隆下来的只有部分主题，会发现有很多空的文件夹。因为这些文件夹里是连接到别的仓库的独立项目。<br>
加上<code>--recursive</code>参数后，就可以把所有子项目都一起克隆下来了:</p>
<div class="highlight"><pre><span></span><code><span class="gp">$ </span>git clone --recursive https://github.com/getpelican/pelican-themes.git
</code></pre></div>

<p>不过要想全部完整的克隆下来，还得网络给力。所以不行的话，只能按需把需要的项目单独下载下来用了。  </p>
<h4 id="pei-zhi-shi-yong-zhu-ti"><a class="toclink" href="#pei-zhi-shi-yong-zhu-ti">配置使用主题</a></h4>
<p>修改 pelicanconf.py 配置文件：</p>
<div class="highlight"><pre><span></span><code><span class="n">THEME</span> <span class="o">=</span> <span class="s1">&#39;pelican-themes/gum&#39;</span>
</code></pre></div>

<h4 id="ying-yong-zhu-ti"><a class="toclink" href="#ying-yong-zhu-ti">应用主题</a></h4>
<p>再执行一次生成静态页面的命令即可：</p>
<div class="highlight"><pre><span></span><code><span class="gp">$ </span>pelican content
<span class="gp">$ </span>pelican --listen
</code></pre></div>

<p>之后可以现在本地看下效果</p>
<h4 id="guan-yu-xiu-gai-zhu-ti"><a class="toclink" href="#guan-yu-xiu-gai-zhu-ti">关于修改主题</a></h4>
<p>别人的模板总有些不喜欢的地方，有能力可以自己修改一下。<br>
推荐的做法是，最好不要直接就去改主题，先去看一下pelican的官方文档<a href="https://pelican-docs-latest-cn.readthedocs.io/zh_CN/latest/themes.html">关于主题</a>的部分。    </p>
<p>先看一下主题的框架，有哪些文件，以及每个文件的作用。再看下最后的例子。  </p>
<p>对框架有了大概的了解之后，再去看使用的主题的项目里的README。  </p>
<h3 id="tian-jia-cha-jian"><a class="toclink" href="#tian-jia-cha-jian">添加插件</a></h3>
<p>可以先不加插件，把博客先开起来。原生的那些功能凑活还是能用的。<br>
不过，通过插件可以对功能进行扩展。  </p>
<h4 id="xia-zai-cha-jian"><a class="toclink" href="#xia-zai-cha-jian">下载插件</a></h4>
<p>和主题一样，有一个库里统一管理了所有的插件，下面的命令是把所有的插件都克隆到本地:</p>
<div class="highlight"><pre><span></span><code><span class="gp">$ </span>git clone --recursive https://github.com/getpelican/pelican-plugins
</code></pre></div>

<p>网络不给力，要完整的克隆下来也未必顺利。按需要把要用的插件单独克隆下来也是一样的。<br>
另外插件的使用也可以去看项目中的README。  </p>
<h4 id="pei-zhi-bing-ying-yong-cha-jian"><a class="toclink" href="#pei-zhi-bing-ying-yong-cha-jian">配置并应用插件</a></h4>
<p>在配置文件中添加插件存放的路径以及要使用的插件:</p>
<div class="highlight"><pre><span></span><code><span class="c1"># PLUGINS</span>
<span class="n">PLUGIN_PATHS</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;plugins&#39;</span><span class="p">]</span>
<span class="n">PLUGINS</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;sitemap&#39;</span><span class="p">,</span> <span class="s1">&#39;category_order&#39;</span><span class="p">,</span> <span class="s1">&#39;w3c_validate&#39;</span><span class="p">,</span> <span class="s1">&#39;optimize_images&#39;</span><span class="p">,</span> <span class="s1">&#39;gzip_cache&#39;</span><span class="p">]</span>

<span class="c1">## SITEMAP PLUGIN</span>
<span class="n">SITEMAP</span> <span class="o">=</span> <span class="p">{</span>
    <span class="s1">&#39;format&#39;</span><span class="p">:</span> <span class="s1">&#39;xml&#39;</span><span class="p">,</span>
    <span class="s1">&#39;priorities&#39;</span><span class="p">:</span> <span class="p">{</span>
        <span class="s1">&#39;articles&#39;</span><span class="p">:</span> <span class="mf">.99</span><span class="p">,</span>
        <span class="s1">&#39;pages&#39;</span><span class="p">:</span> <span class="mf">.75</span><span class="p">,</span>
        <span class="s1">&#39;indexes&#39;</span><span class="p">:</span> <span class="mf">.5</span>
    <span class="p">},</span>
    <span class="s1">&#39;changefreqs&#39;</span><span class="p">:</span> <span class="p">{</span>
        <span class="s1">&#39;articles&#39;</span><span class="p">:</span> <span class="s1">&#39;daily&#39;</span><span class="p">,</span>
        <span class="s1">&#39;pages&#39;</span><span class="p">:</span> <span class="s1">&#39;daily&#39;</span><span class="p">,</span>
        <span class="s1">&#39;indexes&#39;</span><span class="p">:</span> <span class="s1">&#39;daily&#39;</span>
    <span class="p">},</span>
<span class="p">}</span>
</code></pre></div>

<p>另外有些插件还有自己的配置，比如这里的sitemap。  </p>
<p>总的项目目录中有一份所有插件的列表，以及一句话对插件的说明（Description）。具体怎么用，还是进到子项目中查看README吧。  </p>
<h3 id="jing-yan-he-ji-qiao"><a class="toclink" href="#jing-yan-he-ji-qiao">经验和技巧</a></h3>
<p>更多使用中总结的经验和技巧，就继续在这里补充。  </p>
<h4 id="markdown-shi-yong-mao-dian"><a class="toclink" href="#markdown-shi-yong-mao-dian">Markdown 使用锚点</a></h4>
<p>在配置文件中，下面是关于MARKDOWN的配置。其中锚点是在<code>markdown.extensions.toc</code>里的设置：</p>
<div class="highlight"><pre><span></span><code><span class="c1"># pelicanconf.py</span>
<span class="c1"># 生成锚点，在DEFAULT_CONFIG[&#39;MARKDOWN&#39;]的基础上，增加markdown.extensions.toc</span>
<span class="n">MARKDOWN</span> <span class="o">=</span> <span class="p">{</span>
    <span class="s1">&#39;extension_configs&#39;</span><span class="p">:</span> <span class="p">{</span>
        <span class="s1">&#39;markdown.extensions.codehilite&#39;</span><span class="p">:</span> <span class="p">{</span><span class="s1">&#39;css_class&#39;</span><span class="p">:</span> <span class="s1">&#39;highlight&#39;</span><span class="p">},</span>
        <span class="s1">&#39;markdown.extensions.extra&#39;</span><span class="p">:</span> <span class="p">{},</span>
        <span class="s1">&#39;markdown.extensions.meta&#39;</span><span class="p">:</span> <span class="p">{},</span>
        <span class="s1">&#39;markdown.extensions.toc&#39;</span><span class="p">:</span> <span class="p">{</span>  <span class="c1"># class TocExtension(Extension): 的__init__构造函数中self.config的配置项</span>
            <span class="s1">&#39;anchorlink&#39;</span><span class="p">:</span> <span class="kc">True</span><span class="p">,</span>  <span class="c1"># 标题上生成一个指向自己的锚定，会有个超连接的下划线</span>
            <span class="s1">&#39;permalink&#39;</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span>      <span class="c1"># 标题后不添加任何内容，可以是字符串或者True（默认符号）</span>
            <span class="s1">&#39;toc_depth&#39;</span><span class="p">:</span> <span class="s1">&#39;3-4&#39;</span><span class="p">,</span>  <span class="c1"># 只要 h3 和 h4</span>
            <span class="s1">&#39;slugify&#39;</span><span class="p">:</span> <span class="n">slugify_pinyin</span>  <span class="c1"># 使用拼音替换中文字符生成锚点标识</span>
        <span class="p">},</span>
    <span class="p">},</span>
    <span class="s1">&#39;output_format&#39;</span><span class="p">:</span> <span class="s1">&#39;html5&#39;</span><span class="p">,</span>
<span class="p">}</span>
</code></pre></div>

<p><code>'toc_depth': '3-4'</code>，仅为3级至4级标题生成锚点。<br>
<code>'slugify': slugify_pinyin</code>，生成锚点的函数。这项可以不设置，有默认方法，这里用了自定义方法将汉字转成了拼音。  </p>
<p>用下面的格式可以设置跳转到锚点位置，实现在文章中跳转：</p>
<div class="highlight"><pre><span></span><code>[Windows Terminal](#windows-terminal)
</code></pre></div>

<p>中括号里是文本显示的内容。<br>
小括号里指向要跳转的标题：</p>
<ul>
<li>字母全小写</li>
<li>不能有空格，空格换成-</li>
<li>如果有中文标点会被GFM移除</li>
<li>支持中文字符（但是到html里又不支持了）。这个是markdown中的锚点，我们更关注html中的锚点，下面为了实现html的锚点，就不对markdown锚点兼容了。</li>
</ul>
<p>这里提到了GFM 就是 GitHub Flavored Markdown，是标准Markdown的超集。标准Markdown不支持表格和锚点等。表格我一直以为是基本格式并且一直在用，似乎目前我一直用的都是GFM，可以放心了。  </p>
<h5 id="zai-html-zhong-de-bian-hua"><a class="toclink" href="#zai-html-zhong-de-bian-hua">在html中的变化</a></h5>
<p>上面是纯Markdwon的做法，这里要用Pelican转成网页，又会有新的问题。html中需要对文本做转义，中文这种转义后就类似乱码，虽然应该能使用，但是url中显示不友好。为了能有友好的显示，只能使用字母、数字、下划线、中横杠这些字符。这时会使用slugify对文本进行处理，处理后仅会输出友好的字符串。<br>
下面是Pelican的markdown插件中默认的slugify函数处理的逻辑：</p>
<ul>
<li>中文字符也会被移除，只会留下英文</li>
<li>如果是纯中文，那么最后就变成空字符串了</li>
<li>为了防止重名，会在后面加上_1，_2，_3</li>
<li>如果是英文重名，第一个是原文，后面的重名从_1开始</li>
<li>如果是纯中文，那么第一个是_1，只后是_2，_3</li>
</ul>
<p>函数的源码如下：</p>
<div class="highlight"><pre><span></span><code><span class="kn">import</span> <span class="nn">re</span>
<span class="kn">import</span> <span class="nn">unicodedata</span>

<span class="k">def</span> <span class="nf">slugify</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">separator</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot; Slugify a string, to make it URL friendly. &quot;&quot;&quot;</span>
    <span class="n">value</span> <span class="o">=</span> <span class="n">unicodedata</span><span class="o">.</span><span class="n">normalize</span><span class="p">(</span><span class="s1">&#39;NFKD&#39;</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span><span class="o">.</span><span class="n">encode</span><span class="p">(</span><span class="s1">&#39;ascii&#39;</span><span class="p">,</span> <span class="s1">&#39;ignore&#39;</span><span class="p">)</span>
    <span class="n">value</span> <span class="o">=</span> <span class="n">re</span><span class="o">.</span><span class="n">sub</span><span class="p">(</span><span class="sa">r</span><span class="s1">&#39;[^\w\s-]&#39;</span><span class="p">,</span> <span class="s1">&#39;&#39;</span><span class="p">,</span> <span class="n">value</span><span class="o">.</span><span class="n">decode</span><span class="p">(</span><span class="s1">&#39;ascii&#39;</span><span class="p">))</span><span class="o">.</span><span class="n">strip</span><span class="p">()</span><span class="o">.</span><span class="n">lower</span><span class="p">()</span>
    <span class="k">return</span> <span class="n">re</span><span class="o">.</span><span class="n">sub</span><span class="p">(</span><span class="sa">r</span><span class="s1">&#39;[</span><span class="si">%s</span><span class="s1">\s]+&#39;</span> <span class="o">%</span> <span class="n">separator</span><span class="p">,</span> <span class="n">separator</span><span class="p">,</span> <span class="n">value</span><span class="p">)</span>
</code></pre></div>

<p>由于中文都会被忽略，导致大量标题的id都是空，然后加上序号，生成的锚点都是无意义的纯序号锚点。在文章结构变化时，这些锚点的序号也会变化，使得对锚点的引用会发生错误。<br>
这里用自定义的slugify函数解决问题，先将中文转成拼音，使得锚点包含有意义的字符，避免重名。对锚点的引用不会因文章结构的变化而变化：</p>
<div class="highlight"><pre><span></span><code><span class="kn">from</span> <span class="nn">markdown.extensions.toc</span> <span class="kn">import</span> <span class="n">slugify</span>
<span class="kn">from</span> <span class="nn">pypinyin</span> <span class="kn">import</span> <span class="n">lazy_pinyin</span>

<span class="k">def</span> <span class="nf">slugify_pinyin</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">separator</span><span class="o">=</span><span class="s1">&#39;-&#39;</span><span class="p">):</span>
    <span class="sd">&quot;&quot;&quot; 先将中文转换成拼音，再生成锚点 &quot;&quot;&quot;</span>
    <span class="n">value</span> <span class="o">=</span> <span class="s1">&#39; &#39;</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">lazy_pinyin</span><span class="p">(</span><span class="n">value</span><span class="p">))</span>
    <span class="k">return</span> <span class="n">slugify</span><span class="p">(</span><span class="n">value</span><span class="p">,</span> <span class="n">separator</span><span class="p">)</span>
</code></pre></div>

<p>在原有slugify函数的基础上，仅做简单的修改。  </p>
<h5 id="shi-yong-de-jian-yi-jiu-fang-an"><a class="toclink" href="#shi-yong-de-jian-yi-jiu-fang-an">使用的建议（旧方案）</a></h5>
<p>这样就会导致编辑器和网页使用的时候不兼容，只有英文标题才能完全兼容。<br>
这里是针对不使用自定义slugify函数的建议，有了自定义的slugify函数，就不需要按这里建议的做了。<br>
以后修改文件，增加或删除章节，就会使得原来的纯中文标题的锚点改变。至少要在标题中带点英文才能避免锚点改变。<br>
如果要用锚点：</p>
<ol>
<li>纯英文的标题，就放心的愉快的用</li>
<li>增加标题中的英文字符，防止标题锚点重名，这样不容易受到改变目录结构的影响</li>
<li>纯中文的标题就不要用锚点了，以后难以维护</li>
</ol>
<h5 id="yin-yong-bie-de-wen-zhang"><a class="toclink" href="#yin-yong-bie-de-wen-zhang">引用别的文章</a></h5>
<p>上面是跳转本篇文章的位置，如果是其他文章中的位置，使用下面的语法：</p>
<div class="highlight"><pre><span></span><code>[参数化固件]({filename}12_单元测试_pytest2.md#parametrizing-fixtures-can-shu-hua-gu-jian)
</code></pre></div>

<p>小括号中以<code>{filename}</code>开头，后面是文件的相对路径。这个例子是引用当前这篇文章同目录下的文章。  </p>
<h4 id="dai-ma-gao-liang-xian-shi"><a class="toclink" href="#dai-ma-gao-liang-xian-shi">代码高亮显示</a></h4>
<p>代码高亮用的是pygments模块，官方网站：<a href="https://pygments.org/demo/">https://pygments.org/demo/</a> 。<br>
对应语言的名称可以去模块里的lexers目录里搜一下。常用的名称：</p>
<ul>
<li>'text': 纯文本，无高亮显示</li>
<li>'python', 'py', 'sage', 'python3', 'py3'：python3.x</li>
<li>'go'：Go语言</li>
<li>'bash', 'sh', 'ksh', 'zsh', 'shell'：Shell脚本，各种shell似乎都是一样解析的</li>
<li>'console', 'shell-session'：shell sessions，贴命令行用这个</li>
<li>'doscon'：MSDOS的命令行输出</li>
<li>'powershell', 'posh', 'ps1', 'psm1': PowerShell脚本</li>
<li>'ps1con'：PowerShell的命令行输出</li>
<li>'terraform', 'tf': Terraform</li>
<li>'ini', 'cfg', 'dosini': 配置文件</li>
<li>'yaml': YAML</li>
<li>'json': JSON</li>
<li>'docker', 'dockerfile': Dockerfile文件</li>
</ul>
<p><strong>注意：</strong>贴命令行及输出的时候，使用命令行输出的格式的名称，主要能识别到命令提示符。不过关键字的高亮应该就没了。<br>
脚本语言也是编程语言，贴代码就是代码。要附上输出，就写在注释里，或者另外贴出来。<br>
直接贴命令行的内容（Session），就用对应的命令行输出的格式的名称，高亮的似乎只有命令提示符。另外PowerShell的命令提示符的格式是包含最后的一个空格的，最后少个空格也解析不出来。  </p>
      </div>
      <div class="back-to-top">
        <a href="/">HOME</a>
        <a href="#top">TOP</a>
      </div>
    </article>
  </div>
<!-- end article -->
<!-- 页面往下滚动一段之后才会显示TOC -->
<script>
  window.onscroll = function() {
    var tocbox = document.getElementsByClassName('toc')[0];
    var osTop = document.documentElement.scrollTop || document.body.scrollTop;
    var osWidth = document.documentElement.scrollWidth || document.body.scrollWidth;
    // console.log(osTop)
    if (osTop>300 && osWidth>865) {
      tocbox.style.display = "block"
    }
    if (osTop<300 || osWidth<865) {
      tocbox.style.display = "none"
    }
  }
</script>
                <footer>
                    <div class="icons">
                    </div>
                    <span id="busuanzi_container_page_pv" style="padding: 10px">本文阅读量<span id="busuanzi_value_page_pv"></span>次</span>
                    <span id="busuanzi_container_site_pv" style="padding: 10px">本站总访问量<span id="busuanzi_value_site_pv"></span>次</span>
                    <span id="busuanzi_container_site_uv" style="padding: 10px">本站总访客数<span id="busuanzi_value_site_uv"></span>人</span>
                    <p>© <script>document.write(moment().format('YYYY'));</script> 749B</p>
                </footer>
        </div>
</body>
</html>